package org.chen.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.StringEscapeUtils;
import org.chen.common.constants.Constants;
import org.chen.common.constants.PayConstants;
import org.chen.common.exception.ExceptionCodeEnum;
import org.chen.common.exception.FlyingException;
import org.chen.common.model.travel.StoreTravelOrder;
import org.chen.common.model.travel.StoreTravelOrderInfo;
import org.chen.common.page.CommonPage;
import org.chen.common.request.CreateTravelOrderRequest;
import org.chen.common.request.OrderRefundApplyRequest;
import org.chen.common.request.PageParamRequest;
import org.chen.common.request.TravelOrderRequest;
import org.chen.common.response.OrderTravelDetailResponse;
import org.chen.common.response.OrderTravelInfoResponse;
import org.chen.common.response.PreTravelOrderResponse;
import org.chen.common.response.StoreTravelOrderDetailInfoResponse;
import org.chen.common.user.User;
import org.chen.common.utils.DateUtil;
import org.chen.common.utils.FlyingUtil;
import org.chen.common.utils.RedisUtil;
import org.chen.common.vo.MyRecord;
import org.chen.common.vo.OrderTravelInfoVo;
import org.chen.service.*;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    private final UserService userService;
    private final RedisUtil redisUtil;
    private final OrderUtils orderUtils;
    private final SystemConfigService systemConfigService;
    private final StoreTravelOrderService storeTravelOrderService;
    private final StoreOrderStatusService storeOrderStatusService;
    private final StoreTravelOrderInfoService storeTravelOrderInfoService;
    private final KafkaTemplate<String, String> kafkaTemplate;
    private final ObjectMapper objectMapper;
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedissonClient redissonClient;
    private final AsyncValidationService asyncValidationService;
    private final RedissonClient redisson;


    @Autowired
    public OrderServiceImpl(UserService userService, RedisUtil redisUtil, OrderUtils orderUtils,
                            SystemConfigService systemConfigService, StoreTravelOrderService storeTravelOrderService,
                            StoreOrderStatusService storeOrderStatusService, StoreTravelOrderInfoService storeTravelOrderInfoService,
                            KafkaTemplate<String, String> kafkaTemplate, ObjectMapper objectMapper, RedisTemplate<String, Object> redisTemplate,
                            RedissonClient redissonClient, AsyncValidationService asyncValidationService,RedissonClient redisson) {
        this.userService = userService;
        this.redisUtil = redisUtil;
        this.orderUtils = orderUtils;
        this.systemConfigService = systemConfigService;
        this.storeTravelOrderService = storeTravelOrderService;
        this.storeOrderStatusService = storeOrderStatusService;
        this.storeTravelOrderInfoService = storeTravelOrderInfoService;
        this.kafkaTemplate = kafkaTemplate;
        this.objectMapper = objectMapper;
        this.redisTemplate = redisTemplate;
        this.redissonClient = redissonClient;
        this.asyncValidationService = asyncValidationService;
        this.redisson = redisson;
    }

    /**
     * 删除已完成订单(旅游)
     *
     * @param id Integer 订单id
     * @return 删除结果
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean delete(Long id) {
        StoreTravelOrder storeOrder = storeTravelOrderService.getById(id);
        Integer userId = userService.getUserIdException();

        validateOrderDeletion(storeOrder, userId);

        try {
            storeOrder.setIsDel(true);
            storeTravelOrderService.updateById(storeOrder);
            storeOrderStatusService.createTravelLog(storeOrder.getId(), "remove_order", "删除订单");
            return true;
        } catch (Exception e) {
            log.error("Error deleting order: ", e);
            throw new FlyingException(ExceptionCodeEnum.ORDER_DELETION_FAILED, "订单删除失败");
        }
    }

    /**
     * 验证订单删除*
     *
     * @param storeOrder 订单对象
     * @param userId     用户id
     */
    private void validateOrderDeletion(StoreTravelOrder storeOrder, Integer userId) {
        if (ObjectUtil.isNull(storeOrder) || !userId.equals(storeOrder.getUid())) {
            throw new FlyingException(ExceptionCodeEnum.NO_RELEVANT_ORDER_INFORMATION_FOUND, "没有找到相关订单信息!");
        }
        if (storeOrder.getIsDel() || storeOrder.getIsSystemDel()) {
            throw new FlyingException(ExceptionCodeEnum.THE_ORDER_HAS_BEEN_DELETED, "订单已删除!");
        }
        if (storeOrder.getPaid()) {
            if (storeOrder.getRefundStatus() > 0 && !storeOrder.getRefundStatus().equals(1)) {
                throw new FlyingException(ExceptionCodeEnum.ORDERS_CAN_T_BE_DELETED_DURING_THE_REFUND_PROCESS, "订单在退款流程中无法删除!");
            }
            if (storeOrder.getRefundStatus().equals(0) && !storeOrder.getStatus().equals(3)) {
                throw new FlyingException(ExceptionCodeEnum.ONLY_COMPLETED_ORDERS_CAN_BE_DELETED, "只能删除已完成订单!");
            }
        } else {
            throw new FlyingException(ExceptionCodeEnum.UNPAID_ORDERS_CANNOT_BE_DELETED, "未支付订单无法删除!");
        }
    }

    /**
     * 订单取消(旅游)
     *
     * @param id Integer 订单id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancel(Long id) {
        RLock lock = redissonClient.getLock("order_cancel_lock:" + id);
        try {
            // 尝试获取锁，等待5秒后自动释放
            if (!lock.tryLock(5, TimeUnit.SECONDS)) {
                throw new FlyingException(ExceptionCodeEnum.SYSTEM_BUSY, "系统繁忙，请稍后重试");
            }

            StoreTravelOrder storeOrder = storeTravelOrderService.getInfoById(id);
            if (storeOrder == null) {
                throw new FlyingException(ExceptionCodeEnum.ORDER_NOT_EXIST, "订单不存在");
            }

            // 乐观锁检查
            int updatedRows = storeTravelOrderService.updateOrder(id, storeOrder.getVersion());
            if (updatedRows == 0) {
                throw new FlyingException(ExceptionCodeEnum.ORDER_UPDATED, "订单状态已变更，请刷新后重试");
            }

            // 异步处理
            CompletableFuture.runAsync(() -> {
                publishOrderCancelTask(storeOrder);
            });

            return true;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new FlyingException(ExceptionCodeEnum.SYSTEM_ERROR, "取消订单时发生错误");
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    /**
     * 发送Kafka用户取消订单消息*
     * @param storeOrder 订单对象
     */
    private void publishOrderCancelTask(StoreTravelOrder storeOrder) {
        try {
            kafkaTemplate.send("order-cancel-task", objectMapper.writeValueAsString(storeOrder.getId()));
        } catch (JsonProcessingException e) {
            log.error("Failed to publish order created event", e);
        }
    }

    /**
     * 取消退款申请(旅游)
     *
     * @param id Integer 订单id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancelApplication(Long id) {
        StoreTravelOrder storeOrder = storeTravelOrderService.getInfoById(id);
        if (storeOrder == null) {
            throw new FlyingException(ExceptionCodeEnum.ORDER_NOT_EXIST, "订单不存在");
        }
        storeOrder.setRefundStatus(4);
        redisTemplate.delete("refund_processed:" + storeOrder.getOrderId());
        return storeTravelOrderService.updateById(storeOrder);
    }

    /**
     * 订单预下单(旅游)
     *
     * @param request 预下单请求参数
     * @return PreOrderResponse
     */
    @Override
    public MyRecord preOrderTravel(TravelOrderRequest request) {
        if (CollUtil.isEmpty(request.getTabel())) {
            throw new FlyingException(ExceptionCodeEnum.THE_LIST_OF_PRE_PLACED_ORDERS_CANNOT_BE_EMPTY, "预下单订单列表不能为空");
        }
        User user = userService.getTravelInfoException();
        String lockKey = "pre_order_lock:" + user.getUid();
        RLock lock = redissonClient.getLock(lockKey);
        try {
            // 尝试获取锁，等待5秒后自动释放
            if (!lock.tryLock(5, TimeUnit.SECONDS)) {
                throw new FlyingException(ExceptionCodeEnum.SYSTEM_BUSY, "系统繁忙，请稍后重试");
            }

            // 异步校验预下单商品信息
            CompletableFuture<OrderTravelInfoVo> validationFuture = asyncValidationService.validatePreTravelOrderRequest(request);

            String key = generateUniqueKey(user);

            // 等待验证结果
            OrderTravelInfoVo orderTravelInfoVo = validationFuture.get(5, TimeUnit.SECONDS);

            // 使用Redis pipeline
            redisUtil.executePipelined(operations -> {
                operations.opsForValue().set("user_order:" + key, JSONObject.toJSONString(orderTravelInfoVo));
                operations.expire("user_order:" + key, Constants.ORDER_CASH_CONFIRM, TimeUnit.MINUTES);
            });

            MyRecord record = new MyRecord();
            record.set("preOrderNo", key);
            return record;
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            throw new FlyingException(ExceptionCodeEnum.PRE_ORDER_FAILED, "预下单失败");
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    /**
     * 生成唯一锁*
     *
     * @param user 用户
     * @return string
     */
    private String generateUniqueKey(User user) {
        return user.getUid() + DateUtil.getNowTime().toString() + FlyingUtil.getUuid();
    }

    /**
     * 加载预下单信息(旅游)
     *
     * @param preOrderNo 预下单号
     * @return 预下单信息
     */
    @Override
    public PreTravelOrderResponse loadPreTravelOrder(String preOrderNo) {
        // 通过缓存获取预下单对象
        String key = "user_order:" + preOrderNo;
        boolean exists = redisUtil.exists(key);
        if (!exists) {
            throw new FlyingException(ExceptionCodeEnum.THE_PRE_ORDER_DOES_NOT_EXIST, "预下单订单不存在");
        }
        String orderVoString = redisUtil.get(key).toString();
        OrderTravelInfoVo orderTravelInfoVo = JSONObject.parseObject(orderVoString, OrderTravelInfoVo.class);
        PreTravelOrderResponse preTravelOrderResponse = new PreTravelOrderResponse();
        preTravelOrderResponse.setOrderInfoVo(orderTravelInfoVo);
        //开启paypal
        preTravelOrderResponse.setPayPalOpen("1");
        preTravelOrderResponse.setPreOrderNo(preOrderNo);
        return preTravelOrderResponse;
    }

    /**
     * 创建订单(旅游)
     *
     * @param request 创建订单请求参数
     * @return MyRecord 订单编号
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public MyRecord createTravelOrder(CreateTravelOrderRequest request) {
        String lockKey = "order_lock:" + request.getPreOrderNo();
        RLock lock = redissonClient.getLock(lockKey);
        try {
            // 尝试获取锁，等待5秒后自动释放
            if (!lock.tryLock(5, TimeUnit.SECONDS)) {
                throw new FlyingException(ExceptionCodeEnum.ORDER_BEING_PROCESSED, "订单正在处理中，请稍后再试");
            }

            User user = userService.getTravelInfoException();
            String key = "user_order:" + request.getPreOrderNo();

            boolean exists = redisUtil.exists(key);
            if (!exists) {
                throw new FlyingException(ExceptionCodeEnum.THE_PRE_ORDER_DOES_NOT_EXIST, "预下单订单不存在");
            }

            String orderVoString = redisUtil.get(key).toString();

            OrderTravelInfoVo orderTravelInfoVo = parseOrderTravelInfoVo(orderVoString);

            validatePaymentMethod(request);

            String orderNo = generateOrderNo();
            StoreTravelOrder storeOrder = createStoreOrder(user, orderNo, orderTravelInfoVo, request);
            List<StoreTravelOrderInfo> storeOrderInfos = createStoreOrderInfos(orderTravelInfoVo, orderNo);

            storeTravelOrderService.save(storeOrder);
            storeOrderInfos.forEach(info -> info.setOrderId(storeOrder.getId()));
            storeTravelOrderInfoService.saveBatch(storeOrderInfos);
            storeOrderStatusService.createTravelLog(storeOrder.getId(), Constants.ORDER_STATUS_CACHE_CREATE_ORDER, "订单生成");

            publishOrderCreatedEvent(storeOrder);

            redisUtil.delete(key);

            // 计算订单过期时间
            String cancelHours = systemConfigService.getValueByKey("order_cancel_time");
            long expireTime = System.currentTimeMillis() + (long) parseHours(cancelHours) * 3600 * 1000;
            // 使用 ZSET 存储，score 为过期时间戳
            redisUtil.zAdd("order_cancel_delay", storeOrder.getOrderId(), expireTime);
            return createOrderResponse(storeOrder);

        } catch (Exception e){
            redisTemplate.delete("order_processed:" + request.getPreOrderNo());
            log.error("捕获的自定义异常",e);
            throw new FlyingException(ExceptionCodeEnum.SYSTEM_ERROR, "系统繁忙，请稍后再试");
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    /**
     * 解析取消时间配置
     */
    private int parseHours(String cancelStr) {
        if (StrUtil.isBlank(cancelStr)) {
            log.warn("未配置 order_cancel_time，使用默认值3小时");
            return 3;
        }

        try {
            int hours = Integer.parseInt(cancelStr);
            if (hours <= 0 || hours > 72) {
                log.warn("订单取消时间配置超出范围：{}，使用默认值3小时", cancelStr);
                return 3;
            }
            return hours;
        } catch (NumberFormatException e) {
            log.error("订单取消时间配置格式错误：{}，使用默认值3小时", cancelStr, e);
            return 3;
        }
    }

    /**
     * 解析数据为OrderTravelInfoVo
     *
     * @param orderVoString redis里的数据
     * @return OrderTravelInfoVo
     */
    private OrderTravelInfoVo parseOrderTravelInfoVo(String orderVoString) {
        try {
            return objectMapper.readValue(orderVoString, OrderTravelInfoVo.class);
        } catch (JsonProcessingException e) {
            throw new FlyingException(ExceptionCodeEnum.INVALID_ORDER_DATA, "无效的订单数据");
        }
    }

    /**
     * 校验支付方式*
     *
     * @param request 创建旅游订单请求对象
     */
    private void validatePaymentMethod(CreateTravelOrderRequest request) {
        if (!orderUtils.checkPayType(request.getPayType())) {
            throw new FlyingException(ExceptionCodeEnum.THIS_PAYMENT_METHOD_IS_NOT_SUPPORTED_AT_THIS_TIME, "暂不支持该支付方式，请刷新页面或者联系管理员");
        }

        if (PayConstants.PAY_TYPE_PAY_Pal.equals(request.getPayType())) {
            if (StrUtil.isBlank(request.getPayChannel())) {
                throw new FlyingException(ExceptionCodeEnum.THE_PAYMENT_CHANNEL_CANNOT_BE_EMPTY, "支付渠道不能为空!");
            }
            if (!OrderUtils.checkPayChannel(request.getPayChannel())) {
                throw new FlyingException(ExceptionCodeEnum.THE_PAYMENT_CHANNEL_DOES_NOT_EXIST, "支付渠道不存在!");
            }
        }
    }

    /**
     * 生成订单号*
     *
     * @return 订单号
     */
    private String generateOrderNo() {
        return FlyingUtil.getOrderNo("order");
    }

    /**
     * 冥等性检验的方法*
     *
     * @param preOrderNo 预下单号
     * @return boolean
     */
    private boolean isOrderProcessed(String preOrderNo) {
        return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent("order_processed:" + preOrderNo, "true", 10, TimeUnit.MINUTES));
    }

    /**
     * 生成订单的方法*
     *
     * @param user              用户
     * @param orderNo           订单号
     * @param orderTravelInfoVo 订单信息
     * @param request           创建旅游订单请求对象
     * @return StoreTravelOrder
     */
    private StoreTravelOrder createStoreOrder(User user, String orderNo, OrderTravelInfoVo orderTravelInfoVo, CreateTravelOrderRequest request) {
        /*
        冥等性校验,确保即使同一个请求被多次提交，也只会创建一次订单。
         */
        if (!isOrderProcessed(request.getPreOrderNo())) {
            throw new FlyingException(ExceptionCodeEnum.ORDER_ALREADY_PROCESSED, "该订单已经生成,请不要重复提交");
        }

        StoreTravelOrder storeOrder = new StoreTravelOrder();
        storeOrder.setUid(user.getUid());
        storeOrder.setOrderId(orderNo);
        storeOrder.setRealName(orderTravelInfoVo.getOrder().getName());
        storeOrder.setUserPhone(orderTravelInfoVo.getOrder().getMobile());
        storeOrder.setEmail(orderTravelInfoVo.getOrder().getEmail());
        storeOrder.setIsChannel(getIsChannel(request));
        storeOrder.setPaid(false);
        storeOrder.setType(0);
        storeOrder.setStatus(0);
        storeOrder.setRefundStatus(0);
        storeOrder.setIsDel(false);
        storeOrder.setVersion(0);
        storeOrder.setIsSystemDel(false);
        storeOrder.setPayType(request.getPayType());
        storeOrder.setTotalPrice(orderTravelInfoVo.getTotalAmount());
        storeOrder.setCreateTime(DateUtil.nowDateTime());
        storeOrder.setMark(StringEscapeUtils.escapeHtml4(request.getMark()));
        storeOrder.setProTotalPrice(orderTravelInfoVo.getTotalAmount());
        storeOrder.setPayPrice(orderTravelInfoVo.getTotalAmount());
        storeOrder.setTotalNum(orderTravelInfoVo.getTotalCount());
        return storeOrder;
    }

    /**
     * 支付渠道*
     *
     * @param request 创建旅游订单请求对象
     * @return int
     */
    private int getIsChannel(CreateTravelOrderRequest request) {
        if (request.getPayType().equals(PayConstants.PAY_TYPE_PAY_Pal)) {
            return PayConstants.PAY_CHANNEL_H5.equals(request.getPayChannel()) ? 1 : 2;
        }
        return 2;
    }

    /**
     * 生成订单的详细信息*
     *
     * @param orderTravelInfoVo 预下单（旅游）Vo对象
     * @param orderNo           订单号
     * @return list
     */
    private List<StoreTravelOrderInfo> createStoreOrderInfos(OrderTravelInfoVo orderTravelInfoVo, String orderNo) {
        return orderTravelInfoVo.getTableItem().stream()
                .map(detailVo -> {
                    StoreTravelOrderInfo soInfo = new StoreTravelOrderInfo();
                    soInfo.setAllPrice(detailVo.getAllPrice());
                    soInfo.setProductId(detailVo.getProductId());
                    soInfo.setInfo(JSON.toJSON(detailVo).toString());
                    soInfo.setOrderNo(orderNo);
                    soInfo.setPrice(BigDecimal.valueOf(Double.parseDouble(detailVo.getPrice())));
                    soInfo.setPayNum(detailVo.getQuantity());
                    soInfo.setIsReply(false);
                    soInfo.setProductType(detailVo.getType());
                    soInfo.setUnique(UUID.randomUUID().toString());
                    return soInfo;
                })
                .collect(Collectors.toList());
    }

    /**
     * 发kafka消息,通知记录订单数或者通知用户以及其他操作*
     *
     * @param storeOrder 订单对象
     */
    private void publishOrderCreatedEvent(StoreTravelOrder storeOrder) {
        try {
            String orderJson = objectMapper.writeValueAsString(storeOrder);
            kafkaTemplate.send("order-created", orderJson);
        } catch (JsonProcessingException e) {
            log.error("Failed to publish order created event", e);
        }
    }

    /**
     * 返回给前端的响应值*
     *
     * @param storeOrder 订单对象
     * @return MyRecord
     */
    private MyRecord createOrderResponse(StoreTravelOrder storeOrder) {
        MyRecord record = new MyRecord();
        record.set("orderNo", storeOrder.getOrderId());
        record.set("orderId", storeOrder.getId());
        return record;
    }

    /**
     * 订单详情（旅游）
     *
     * @param orderId 订单id
     */
    @Override
    public StoreTravelOrderDetailInfoResponse orderTravelDetail(String orderId) {
        User currentUser = userService.getTravelInfoException();

        StoreTravelOrderDetailInfoResponse storeTravelOrderDetailInfoResponse = new StoreTravelOrderDetailInfoResponse();
        // 查询订单
        StoreTravelOrder storeOrder = storeTravelOrderService.getByOderId(orderId);
        if (ObjectUtil.isNull(storeOrder) || storeOrder.getIsDel() || storeOrder.getIsSystemDel()) {
            throw new FlyingException(ExceptionCodeEnum.THE_ORDER_DOES_NOT_EXIST, "订单不存在");
        }
        if (!storeOrder.getUid().equals(currentUser.getUid())) {
            throw new FlyingException(ExceptionCodeEnum.THE_ORDER_DOES_NOT_EXIST, "订单不存在");
        }

        BeanUtils.copyProperties(storeOrder, storeTravelOrderDetailInfoResponse);
        MyRecord orderStatusVo = getOrderTravelStatusVo(storeOrder);
        // 订单详情对象列表
        List<OrderTravelInfoResponse> infoResponseList = CollUtil.newArrayList();
        List<StoreTravelOrderInfo> infoList = storeTravelOrderInfoService.getListByOrderNoTravel(storeOrder.getOrderId());
        infoList.forEach(e -> {
            OrderTravelInfoResponse orderInfoResponse = new OrderTravelInfoResponse();
            orderInfoResponse.setStoreName(e.getProductName());
            orderInfoResponse.setImage(e.getImage());
            orderInfoResponse.setNum(e.getPayNum());
            orderInfoResponse.setPrice(e.getPrice());
            orderInfoResponse.setAllPrice(e.getAllPrice());
            orderInfoResponse.setProductId(e.getProductId());
            orderInfoResponse.setIsReply(e.getIsReply() ? 1 : 0);
            infoResponseList.add(orderInfoResponse);
        });
        storeTravelOrderDetailInfoResponse.setOrderInfoList(infoResponseList);

        BeanUtils.copyProperties(storeOrder, storeTravelOrderDetailInfoResponse);
        storeTravelOrderDetailInfoResponse.setStatusPic(orderStatusVo.getStr("statusPic"));
        storeTravelOrderDetailInfoResponse.setOrderStatusMsg(orderStatusVo.getStr("msg"));
        storeTravelOrderDetailInfoResponse.setPayTypeStr(orderStatusVo.getStr("payTypeStr"));
        storeTravelOrderDetailInfoResponse.setProTotalPrice(storeOrder.getProTotalPrice());
        return storeTravelOrderDetailInfoResponse;
    }

    /**
     * 订单列表（旅游）
     *
     * @param type        类型
     * @param pageRequest 分页
     * @return CommonPage<OrderDetailResponse>
     */
    @Override
    public CommonPage<OrderTravelDetailResponse> orderTravelList(Integer type, PageParamRequest pageRequest) {
        Integer userId = userService.getUserIdException();

        Page<StoreTravelOrder> userOrderList = storeTravelOrderService.getUserOrderList(userId, type, pageRequest);
        CommonPage<StoreTravelOrder> storeOrderCommonPage = CommonPage.page(userOrderList);
        List<OrderTravelDetailResponse> responseList = CollUtil.newArrayList();
        for (StoreTravelOrder storeOrder : userOrderList.getRecords()) {
            OrderTravelDetailResponse infoResponse = new OrderTravelDetailResponse();
            BeanUtils.copyProperties(storeOrder, infoResponse);
            // 订单状态
            infoResponse.setId(storeOrder.getId().toString());
            infoResponse.setOrderStatus(getH5TravelOrderStatus(storeOrder));
            MyRecord orderStatusVo = getOrderTravelStatusVo(storeOrder);
            infoResponse.setOrderStatusMsg(orderStatusVo.getStr("msg"));
            // 订单详情对象列表
            List<StoreTravelOrderInfo> orderInfoList = storeTravelOrderInfoService.getListByOrderNoTravel(storeOrder.getOrderId());
            List<OrderTravelInfoResponse> infoResponseList = CollUtil.newArrayList();
            orderInfoList.forEach(e -> {
                OrderTravelInfoResponse orderInfoResponse = new OrderTravelInfoResponse();
                orderInfoResponse.setStoreName(e.getProductName());
                orderInfoResponse.setImage(e.getImage());
                orderInfoResponse.setAllPrice(e.getAllPrice());
                orderInfoResponse.setIsReply(e.getIsReply() ? 1 : 0);
                orderInfoResponse.setNum(e.getPayNum());
                orderInfoResponse.setPrice(e.getPrice());
                orderInfoResponse.setProductId(e.getProductId());
                infoResponseList.add(orderInfoResponse);
            });
            infoResponse.setOrderInfoList(infoResponseList);
            responseList.add(infoResponse);
        }
        CommonPage<OrderTravelDetailResponse> detailPage = CommonPage.restPage(responseList);
        BeanUtils.copyProperties(storeOrderCommonPage, detailPage, "list");
        return detailPage;
    }

    /**
     * 订单使用（旅游）
     *
     * @param id Integer 订单id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean take(Long id) {
        RLock lock = redissonClient.getLock("order_take_lock:" + id);
        try {
            // 尝试获取锁，等待5秒后自动释放
            if (!lock.tryLock(5,TimeUnit.SECONDS)) {
                throw new FlyingException(ExceptionCodeEnum.SYSTEM_BUSY, "系统繁忙，请稍后重试");
            }

            // 使用乐观锁更新订单状态
            int updatedRows = storeTravelOrderService.updateOrderStatus(
                    id,
                    Constants.ORDER_STATUS_INT_SPIKE,
                    Constants.ORDER_STATUS_INT_BARGAIN
            );

            if (updatedRows == 0) {
                throw new FlyingException(ExceptionCodeEnum.THE_ORDER_STATUS_IS_INCORRECT, "订单状态已改变，无法使用");
            }

            // 异步处理后续操作
            CompletableFuture.runAsync(() -> {
                StoreTravelOrder storeOrder = storeTravelOrderService.getById(id);
                publishOrderCompletedTask(storeOrder);
            });

            return true;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("尝试获取订单使用锁时中断", e);
            throw new FlyingException(ExceptionCodeEnum.SYSTEM_ERROR, "系统繁忙，请稍后再试");
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    /**
     * 发送Kafka用户使用订单消息*
     * @param storeOrder 订单对象
     */
    private void publishOrderCompletedTask(StoreTravelOrder storeOrder) {
        try {
            kafkaTemplate.send("order-completed_task", objectMapper.writeValueAsString(storeOrder.getId()));
        } catch (JsonProcessingException e) {
            log.error("Failed to publish order refund task", e);
        }
    }

    /**
     * 获取订单详情信息(旅游)
     *
     * @return StoreTravelOrderDetailInfoResponse
     */
    @Override
    public StoreTravelOrderDetailInfoResponse orderTravelDetailById(Long id) {
        User currentUser = userService.getTravelInfoException();

        StoreTravelOrderDetailInfoResponse storeTravelOrderDetailInfoResponse = new StoreTravelOrderDetailInfoResponse();
        // 查询订单
        StoreTravelOrder storeOrder = storeTravelOrderService.getById(id);

        if (storeOrder.getStatus() == 3) {
            throw new FlyingException(ExceptionCodeEnum.THE_ORDER_HAS_EXPIRED, "订单已失效");
        }

        if (ObjectUtil.isNull(storeOrder) || storeOrder.getIsDel() || storeOrder.getIsSystemDel()) {
            throw new FlyingException(ExceptionCodeEnum.THE_ORDER_DOES_NOT_EXIST, "订单不存在");
        }

        if (!storeOrder.getUid().equals(currentUser.getUid())) {
            throw new FlyingException(ExceptionCodeEnum.THE_ORDER_DOES_NOT_EXIST, "订单不存在");
        }

        BeanUtils.copyProperties(storeOrder, storeTravelOrderDetailInfoResponse);
        storeTravelOrderDetailInfoResponse.setId(storeOrder.getId().toString());
        MyRecord orderStatusVo = getOrderTravelStatusVo(storeOrder);
        // 订单详情对象列表
        List<OrderTravelInfoResponse> infoResponseList = CollUtil.newArrayList();
        List<StoreTravelOrderInfo> infoList = storeTravelOrderInfoService.getListByOrderNoTravel(storeOrder.getOrderId());
        infoList.forEach(e -> {
            OrderTravelInfoResponse orderInfoResponse = new OrderTravelInfoResponse();
            orderInfoResponse.setStoreName(e.getProductName());
            orderInfoResponse.setImage(e.getImage());
            orderInfoResponse.setNum(e.getPayNum());
            orderInfoResponse.setPrice(e.getPrice());
            orderInfoResponse.setAllPrice(e.getAllPrice());
            orderInfoResponse.setProductId(e.getProductId());
            orderInfoResponse.setIsReply(e.getIsReply() ? 1 : 0);
            infoResponseList.add(orderInfoResponse);
        });
        storeTravelOrderDetailInfoResponse.setOrderInfoList(infoResponseList);

        BeanUtils.copyProperties(storeOrder, storeTravelOrderDetailInfoResponse);
        storeTravelOrderDetailInfoResponse.setPayId(storeOrder.getPayId());
        storeTravelOrderDetailInfoResponse.setStatusPic(orderStatusVo.getStr("statusPic"));
        storeTravelOrderDetailInfoResponse.setOrderStatusMsg(orderStatusVo.getStr("msg"));
        storeTravelOrderDetailInfoResponse.setPayTypeStr(orderStatusVo.getStr("payTypeStr"));
        storeTravelOrderDetailInfoResponse.setRefundReason(storeOrder.getRefundReason());
        storeTravelOrderDetailInfoResponse.setProTotalPrice(storeOrder.getProTotalPrice());
        return storeTravelOrderDetailInfoResponse;
    }

    /**
     * 订单退款申请
     * @param request OrderRefundApplyRequest 退款参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean refundApply(OrderRefundApplyRequest request) {
        String lockKey = "refund_lock:" + request.getUni();
        RLock lock = redisson.getLock(lockKey);

        try {
            if (!lock.tryLock(5,TimeUnit.SECONDS)) {
                throw new FlyingException(ExceptionCodeEnum.SYSTEM_BUSY, "系统繁忙，请稍后重试");
            }

            // 幂等性检查
            if (redisUtil.exists("refund_processed:" + request.getUni())) {
                throw new FlyingException(ExceptionCodeEnum.REFUND_ALREADY_PROCESSED, "退款频繁,请1小时后再试");
            }

            StoreTravelOrder existStoreOrder = storeTravelOrderService.getByOrderIdWithLock(request.getUni());
            if (existStoreOrder == null) {
                throw new FlyingException(ExceptionCodeEnum.THE_PAYMENT_SLIP_DOES_NOT_EXIST, "支付订单不存在");
            }

            validateRefundRequest(existStoreOrder);

            // 更新订单状态为退款申请中
            existStoreOrder.setRefundStatus(1);
            existStoreOrder.setRefundReasonTime(DateUtil.nowDateTime());
            existStoreOrder.setRefundReasonWap(request.getText());
            existStoreOrder.setRefundReasonWapExplain(request.getExplain());
            existStoreOrder.setRefundPrice(BigDecimal.ZERO);

            boolean updateResult = storeTravelOrderService.updateById(existStoreOrder);
            if (!updateResult) {
                throw new FlyingException(ExceptionCodeEnum.ORDER_UPDATE_FAILED, "订单状态更新失败");
            }

            // 标记退款申请已处理
            redisUtil.set("refund_processed:" + request.getUni(), "1", Constants.TOKEN_EXPRESS_MINUTES_1, TimeUnit.MINUTES);

            return true;
        }catch (Exception e) {
            log.error("Refund application failed", e);
            redisTemplate.delete("refund_processed:" + request.getUni());
            throw new FlyingException(ExceptionCodeEnum.THE_REFUND_REQUEST_FAILED, "申请退款失败: " + e.getMessage());
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    private void validateRefundRequest(StoreTravelOrder order) {
        if (order.getRefundStatus() == 1) {
            throw new FlyingException(ExceptionCodeEnum.REQUESTING_A_REFUND, "正在申请退款中");
        }
        if (order.getRefundStatus() == 2) {
            throw new FlyingException(ExceptionCodeEnum.THE_ORDER_HAS_BEEN_REFUNDED, "订单已退款");
        }
        if (order.getRefundStatus() == 3) {
            throw new FlyingException(ExceptionCodeEnum.THE_ORDER_IS_BEING_REFUNDED, "订单退款中");
        }
    }

    /**
     * 获取订单状态相关信息(旅游)
     *
     * @return MyRecord
     */
    private MyRecord getOrderTravelStatusVo(StoreTravelOrder storeOrder) {
        MyRecord record = new MyRecord();
        if (!storeOrder.getPaid()) {
            record.set("type", 0);
            record.set("title", "未支付");
            record.set("msg", "订单未支付");
            List<String> configKeys = new ArrayList<>();
            configKeys.add("order_cancel_time");
            List<String> configValues = systemConfigService.getValuesByKes(configKeys);
            Date timeSpace;
            timeSpace = DateUtil.addSecond(storeOrder.getCreateTime(), Double.valueOf(configValues.get(0)).intValue() * 3600);
            record.set("msg", "请在" + DateUtil.dateToStr(timeSpace, Constants.DATE_FORMAT) + "前完成支付");
        } else if (storeOrder.getRefundStatus() == 1) {
            record.set("type", -1);
            record.set("title", "申请退款中");
            record.set("msg", "审核中,请耐心等待");
        } else if (storeOrder.getRefundStatus() == 2) {
            record.set("type", -2);
            record.set("title", "已退款");
            record.set("msg", "已为您退款,感谢您的支持");
        } else if (storeOrder.getRefundStatus() == 3) {
            record.set("type", -3);
            record.set("title", "退款中");
            record.set("msg", "正在为您退款,感谢您的支持");
        }else if (storeOrder.getRefundStatus() == 4) {
            record.set("type", -3);
            record.set("title", "退款失败");
            record.set("msg", "如有疑问请联系客服,感谢您的支持");
        } else if (storeOrder.getStatus() == 1) {
            record.set("type", 0);
            record.set("title", "未使用");
            record.set("msg", "我们会主动联系你,请耐心等待");
        } else if (storeOrder.getStatus() == 2) {
            record.set("type", 1);
            record.set("title", "已使用，待评价");
            record.set("msg", "已使用,快去评价一下吧");
        } else if (storeOrder.getStatus() == 3) {
            record.set("type", 2);
            record.set("title", "交易完成");
            record.set("msg", "交易完成,感谢您的支持");
        }

        // 支付方式
        String orderPayTypeStr = orderUtils.getOrderPayTypeStr(storeOrder.getPayType());
        record.set("payTypeStr", orderPayTypeStr);
        return record;
    }

    /**
     * 获取H5订单状态（旅游）
     *
     * @param storeOrder 订单对象
     */
    private String getH5TravelOrderStatus(StoreTravelOrder storeOrder) {
        if (!storeOrder.getPaid()) {
            if (storeOrder.getStatus().equals(3)) {
                return "已取消";
            }
            return "待支付";
        }
        if (storeOrder.getRefundStatus().equals(1)) {
            return "申请退款中";
        }
        if (storeOrder.getRefundStatus().equals(2)) {
            return "已退款";
        }
        if (storeOrder.getRefundStatus().equals(3)) {
            return "退款中";
        }
        if (storeOrder.getRefundStatus().equals(4)) {
            return "退款失败";
        }
        if (storeOrder.getStatus().equals(1)) {
            if (storeOrder.getRefundStatus().equals(4)){
                return "待使用";
            }
            return "待使用";
        }
        if (storeOrder.getStatus().equals(2)) {
            return "已完成";
        }
        if (storeOrder.getStatus().equals(3)) {
            return "已取消";
        }
        return "";
    }


}


